/*
 * Copyright 2010-2012 Susanta Tewari. <freecode4susant@users.sourceforge.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package test.coalescent.data;

import com.google.common.collect.ImmutableMap;
import commons.util.MathUtil;
import test.commons.core.IgnoredDataTDFilter;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;

import static test.coalescent.data.ModelTestDataInstances.*;

/**
 * @author Susanta Tewari
 */
public class DataTestDataInstances {

    /** Field description */
    public static final String heinK69DataUIDPrefix = K69DataTestData.class.getName() + "-"
                                                      + "hein2005Book-";

    /** Field description */
    public static final String heinKC64DataUIDPrefix = KC64DataTestData.class.getName() + "-"
                                                       + "hein2005Book-";

    /** Field description */
    public static final String wakeleyK69DataUIDPrefix = K69DataTestData.class.getName() + "-"
                                                         + "wakeley2009Book-";

    /** Field description */
    public static final String spougeK69DataUIDPrefix = K69DataTestData.class.getName() + "-"
                                                        + "Spouge-";

    /** Field description */
    public static final String tewariK69DataUIDPrefix = K69DataTestData.class.getName() + "-"
                                                        + "Tewari-";

    /**
     * Constructs ...
     *
     */
    private DataTestDataInstances() {}

    /**
     * Method description
     *
     *
     * @param filterIgnoredData
     *
     * @return
     */
    public static Collection<? extends PopGenDataTestData> getPopGenDataTestDataInstances(
            boolean filterIgnoredData) {

        Collection<PopGenDataTestData> collection = new ArrayList<>(10);

        collection.addAll(getKC64DataTestDataInstances(filterIgnoredData));

        return collection;
    }

    /**
     * Method description
     *
     *
     * @param filterIgnoredData
     *
     * @return
     */
    public static Collection<? extends KC64DataTestData> getKC64DataTestDataInstances(
            boolean filterIgnoredData) {

        Collection<DefaultK69DataTestData> collection = getHeinK69DataTestDataInstances();


        // set prefix
        for (DefaultK69DataTestData val : collection) {
            val.setUidPrefix(heinKC64DataUIDPrefix);
        }

        return IgnoredDataTDFilter.filter(collection, filterIgnoredData);
    }

    /**
     * Method description
     *
     *
     * @param filterIgnoredData
     *
     * @return
     */
    @SuppressWarnings("ReturnOfCollectionOrArrayField")
    public static Collection<? extends K69DataTestData> getK69DataTestDataInstances(
            boolean filterIgnoredData) {

        Collection<K69DataTestData> collection = new ArrayList<>(20);

        collection.addAll(getHeinK69DataTestDataInstances());
        collection.addAll(getSpougeK69DataTestDataInstances());
        collection.addAll(getTewariK69DataTestDataInstances());

        return IgnoredDataTDFilter.filter(collection, filterIgnoredData);
    }


    // <editor-fold defaultstate="collapsed" desc="Collect K69 Data">

    /**
     * Method description
     *
     *
     * @return
     */
    private static Collection<DefaultK69DataTestData> getHeinK69DataTestDataInstances() {

        Collection<DefaultK69DataTestData> heinK69DataTestDataInstances = new ArrayList<>(20);


        // add hein data
        heinK69DataTestDataInstances.add(new DefaultK69DataTestData("D-2-2", THETA_1_0, false,
                ImmutableMap.of("1", 1, "0", 1)));
        heinK69DataTestDataInstances.add(new DefaultK69DataTestData("D-3-1", THETA_1_0, false,
                ImmutableMap.of("1", 1, "0", 2)));
        heinK69DataTestDataInstances.add(new DefaultK69DataTestData("D-3-2", THETA_1_0, false,
                ImmutableMap.of("11", 1, "00", 1)));
        heinK69DataTestDataInstances.add(new DefaultK69DataTestData("D-3-3", THETA_1_0, false,
                ImmutableMap.of("1", 2, "0", 1)));
        heinK69DataTestDataInstances.add(new DefaultK69DataTestData("D-4-1", THETA_1_0, false,
                ImmutableMap.of("11", 1, "00", 2)));
        heinK69DataTestDataInstances.add(new DefaultK69DataTestData("D-4-2", THETA_1_0, false,
                ImmutableMap.of("10", 1, "01", 1, "00", 1)));
        heinK69DataTestDataInstances.add(new DefaultK69DataTestData("D-4-3", THETA_1_0, false,
                ImmutableMap.of("1", 2, "0", 2)));
        heinK69DataTestDataInstances.add(new DefaultK69DataTestData("D-4-4", THETA_1_0, false,
                ImmutableMap.of("11", 2, "00", 1)));
        heinK69DataTestDataInstances.add(new DefaultK69DataTestData("D-5-1", THETA_1_0, false,
                ImmutableMap.of("110", 1, "001", 1, "000", 1)));
        heinK69DataTestDataInstances.add(new DefaultK69DataTestData("D-5-2", THETA_1_0, false,
                ImmutableMap.of("10", 1, "01", 2, "00", 1)));
        heinK69DataTestDataInstances.add(new DefaultK69DataTestData("D-5-3", THETA_1_0, false,
                ImmutableMap.of("11", 2, "00", 2)));
        heinK69DataTestDataInstances.add(new DefaultK69DataTestData("D-5-4", THETA_1_0, false,
                ImmutableMap.of("110", 1, "111", 1, "000", 1)));
        heinK69DataTestDataInstances.add(new DefaultK69DataTestData("D-6-1", THETA_1_0, false,
                ImmutableMap.of("110", 1, "001", 2, "000", 1)));
        heinK69DataTestDataInstances.add(new DefaultK69DataTestData("D-6-2", THETA_1_0, false,
                ImmutableMap.of("110", 2, "001", 1, "000", 1)));
        heinK69DataTestDataInstances.add(new DefaultK69DataTestData("D-6-3", THETA_1_0, false,
                ImmutableMap.of("110", 1, "111", 1, "000", 2)));
        heinK69DataTestDataInstances.add(new DefaultK69DataTestData("D-7-1", THETA_1_0, false,
                ImmutableMap.of("110", 2, "001", 2, "000", 1)));
        heinK69DataTestDataInstances.add(new DefaultK69DataTestData("D-7-2", THETA_1_0, false,
                ImmutableMap.of("1100", 1, "1110", 1, "0001", 1, "0000", 1)));
        heinK69DataTestDataInstances.add(new DefaultK69DataTestData("D-8-1", THETA_1_0, true,
                ImmutableMap.of("1100", 1, "1110", 1, "0001", 2, "0000", 1)));


        // add hein prefix
        for (DefaultK69DataTestData val : heinK69DataTestDataInstances) {
            val.setUidPrefix(heinK69DataUIDPrefix);
        }

        return heinK69DataTestDataInstances;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    private static Collection<DefaultK69DataTestData> getSpougeK69DataTestDataInstances() {

        Collection<DefaultK69DataTestData> instances = new ArrayList<>(20);


        // add john data
        instances.add(new DefaultK69DataTestData("J-1", THETA_1_0, true,
                ImmutableMap.of("110", 2, "001", 2)));
        instances.add(new DefaultK69DataTestData("J-2", THETA_1_0, true,
                ImmutableMap.of("1", 3, "0", 2)));
        instances.add(new DefaultK69DataTestData("J-3", THETA_1_0, true,
                ImmutableMap.of("1", 3, "0", 3)));


        // add spouge prefix
        for (DefaultK69DataTestData val : instances) {
            val.setUidPrefix(spougeK69DataUIDPrefix);
        }

        return instances;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    @SuppressWarnings("static-access")
    private static Collection<DefaultK69DataTestData> getTewariK69DataTestDataInstances() {

        Collection<DefaultK69DataTestData> instances = new ArrayList<>(20);

        instances.add(new DefaultK69DataTestData("T-1", THETA_1_0, true,
                ImmutableMap.of("11000", 2, "11100", 1, "11010", 1, "00001", 2, "00000", 1)));
        instances.add(new DefaultK69DataTestData("T-2", THETA_1_0, true,
                ImmutableMap.of("1100000", 1, "1110000", 1, "0001100", 1, "0001110", 1, "0000001",
                                2).of("0000000", 1)));
        instances.add(new DefaultK69DataTestData("T-3", THETA_1_0, true,
                ImmutableMap.of("1100", 2, "0011", 1, "0000", 1)));


        // add tewari prefix
        for (DefaultK69DataTestData val : instances) {
            val.setUidPrefix(tewariK69DataUIDPrefix);
        }

        return instances;
    }


    // </editor-fold>

    /**
     * Class description
     *
     *
     * @version        Enter version here..., 12/10/09
     * @author         Susanta Tewari
     */
    private static class DefaultK69DataTestData implements K69DataTestData {

        /** Field description */
        private String uidPrefix = heinK69DataUIDPrefix;

        /** Field description */
        private final String UID;

        /** Field description */
        private final K69TestData model;

        /** Field description */
        private final Map<String, Integer> alleleFreq;

        /** Field description */
        private final boolean ignored;

        DefaultK69DataTestData(String UID, K69TestData model, boolean ignored,
                               Map<String, Integer> alleleFreq) {

            this.UID        = UID;
            this.model      = model;
            this.alleleFreq = alleleFreq;
            this.ignored    = ignored;
        }

        /**
         * Method description
         *
         *
         * @return
         */
        @Override
        public K69TestData getModel() {
            return model;
        }

        /**
         * Method description
         *
         *
         * @return
         */
        @Override
        @SuppressWarnings("ReturnOfCollectionOrArrayField")
        public Map<String, Integer> getAlleleFreq() {
            return alleleFreq;
        }

        /**
         * Method description
         *
         *
         * @return
         */
        @Override
        public Integer getSampleSize() {
            return MathUtil.sumDoublePrecision(alleleFreq.values()).intValue();
        }

        /**
         * Method description
         *
         *
         * @return
         */
        @Override
        public String getUID() {
            return uidPrefix + UID;
        }

        /**
         * Method description
         *
         *
         * @return
         */
        @Override
        public boolean isIgnored() {
            return ignored;
        }

        /**
         * Method description
         *
         *
         * @param uidPrefix
         */
        public void setUidPrefix(String uidPrefix) {
            this.uidPrefix = uidPrefix;
        }
    }
}
